package org.webbase.common.export;

import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

/**
 * pdf工具类
 * @author zhanngle
 */
@Component
public class PdfUtil {
	
	private static final Logger logger = LogManager.getLogger(PdfUtil.class.getName());
	private static ExecutorService executor;
	
	@PostConstruct
	private void init() {
		executor=Executors.newFixedThreadPool(1,new ThreadFactory() {
			public Thread newThread(Runnable run) {
				Thread t=new Thread(run,"pdfutil");
				t.setDaemon(false);
				return t;
			}
		});
	}
	
	@PreDestroy
	private void destroy() {
		executor.shutdown();
	}
	
	/**
	 * 将doc文档转换为pdf文档
	 * 内部会排队转换
	 * @param docfile
	 * @param pdffile
	 * @return
	 */
	public void doc2pdf(final File docfile,final File pdffile) {
		
		executor.execute(new Runnable() {
			public void run() {
				if(!docfile.exists()) {
					throw new RuntimeException("docfile不存在:"+docfile.getAbsolutePath());
				}
				if(!pdffile.getParentFile().exists()) {
					pdffile.getParentFile().mkdirs();
				}
				if(pdffile.exists()) {
					pdffile.delete();
				}
				logger.info("doc2pdf  doc:{}  pdf:{}",docfile.getAbsolutePath(),pdffile.getAbsolutePath());
				doc2pdf2(docfile.getAbsolutePath(),pdffile.getAbsolutePath());
			}
		});
	}
	
	/**
	 * 将doc文档转换为pdf文档
	 * 使用wps word转换
	 * @param docfile
	 * @param pdffile
	 * @return
	 */
	private boolean doc2pdf(String docfile,String pdffile) {
		
		ActiveXComponent wps=null;
        try {
        	wps = new ActiveXComponent("wps.application");
            ActiveXComponent doc = wps.invokeGetComponent("Documents").invokeGetComponent("Open", new Variant(docfile));
            doc.invoke("ExportPdf", new Variant(pdffile));
            doc.invoke("Close");
            doc.safeRelease();
            return true;
        } catch (Exception ex) {
            logger.error("doc2pdf by wps转换失败!",ex);
            return false;
        } finally {
            if (wps != null) {
                wps.invoke("Terminate");
                wps.safeRelease();
            }
        }
	}

	/**
	 * 将doc文档转换为pdf文档
	 * 使用ms office word转换
	 * @param docfile
	 * @param pdffile
	 * @return
	 */
	private boolean doc2pdf2(String docfile,String pdffile) {
		
		ActiveXComponent word=null;
		try {
			word=new ActiveXComponent("Word.Application");
			word.setProperty("Visible", new Variant(false));
			Object docs = word.getProperty("Documents").toDispatch();
			Dispatch doc = Dispatch.invoke(
					(Dispatch) docs, 
					"Open",
					Dispatch.Method, 
					new Object[] { docfile }, 
					new int[1]
				).toDispatch();
			
			Dispatch.invoke(
					doc, 
					"SaveAs", 
					Dispatch.Method,
					new Object[] { pdffile, new Variant(17) }, 
					new int[1]);
			
			Dispatch.invoke(
					doc, 
					"Close", 
					Dispatch.Method,
					new Object[] { new Variant(false) }, 
					new int[1]);
			
			doc.safeRelease();
			return true;
		} catch (Exception e) {
			logger.error("doc2pdf by office转换失败!",e);
			return false;
		} finally {
			if(word!=null) {
				word.invoke("Quit", new Variant[] {});
				word.safeRelease();
			}
		}
	}
	
	public static void main(String[] args) {
		PdfUtil pdfutil=new PdfUtil();
		pdfutil.init();
		pdfutil.doc2pdf2("d:/test.doc", "d:/test.pdf");
		pdfutil.destroy();
	}
}
